import {
  getDocOriginalKey,
  pickedFaceData,
  pickedLineData,
  pickedVertexData,
} from '@amcax/base';
import { PRODUCT_EVENT } from '@app-base/common/Constants';
import { ctx2, userEvents } from '@app-base/module';
import { PickInputRJSFFormat } from '@app-cad/common/components/command-form/constants';
import { PickableCommandForm } from '@app-cad/common/components/command-form/pickable';
import { useCommand } from '@app-cad/common/hooks/useCommand';
import { useDocumentConsumer } from '@app-cad/common/providers/documentProvider';
import { MessageTip } from '@app-cad/common/utils/MessageTip';
import {
  get1stLevelPartFromId,
  getKeyConstraintArr,
  noSystemReferences,
} from '@app-cad/environments/product/utils';
import { httpApi, wsApi } from '@app-cad/server';
import { RJSFSchema } from '@rjsf/utils';
import i18n from 'i18next';
import { isEmpty } from 'lodash';
import { useEffect, useState } from 'react';

type FormData = {
  select: (pickedLineData & pickedFaceData) & pickedVertexData;
  target: string;
};

function ExchangeDoc({ title, onClose }) {
  const [targetOneOf, setTargetOneOf] = useState([]);
  const [formData, setFormData] = useState<FormData>(null);
  const { docTree } = useDocumentConsumer();

  useEffect(() => {
    httpApi
      .getDocuments(docTree.documentInfo.collectionId, false, {
        ref: true,
        pid: getDocOriginalKey(docTree.key),
        pv: docTree.documentInfo.versionDetailResultVo.version,
      })
      .then(({ data }) => {
        const list = data.personalWorkspace
          .concat(data.projectDirectory)
          .filter((item) => item?.documentRefResultVO?.enable);
        const targetOneOfList = list.map((item) => {
          return {
            title: item.name,
            type: 'string',
            const: `${item.documentUuid}@${item.latestVersion.version}`,
          };
        });
        setTargetOneOf(targetOneOfList);
      });
  }, []);

  const isFormDataValid = () =>
    formData?.select != null && formData?.target != null;

  const checkAndFinish = async () => {
    if (!isFormDataValid()) {
      return;
    }

    const part = get1stLevelPartFromId(formData.select?.idInfo?.o);

    if (!part) {
      return;
    }

    const [docId, docVer] = formData.target.split('@');
    const params = {
      o: part.key,
      docid: docId,
      docver: docVer,
    };
    await wsApi.assembleExchangeProduct(params);

    const constraintArr = getKeyConstraintArr(docTree, part.key);

    if (!isEmpty(constraintArr)) {
      const constraintKeyArr = constraintArr?.map((i) => i?.key);
      const constraintNameArr = constraintArr?.map((i) => i?.title);
      MessageTip.warning(
        `同时会移除替换零件的约束 ${constraintNameArr?.join(',')}。`,
      );

      // todo 接口暂时只支持一个个移除约束
      constraintKeyArr.forEach(async (key) => {
        await ctx2.commandCenters.assemblyCommands.deleteConstraint(key);
      });

      userEvents.emit(PRODUCT_EVENT.UPDATE_CONSTRAINTS);
    }

    onClose();
  };

  useCommand('cmd-exchange', {
    onClose,
    finishDraw: checkAndFinish,
  });

  const schema: RJSFSchema = {
    properties: {
      select: {
        type: 'number',
        title: '现有零部件',
        format: PickInputRJSFFormat.PickProduct,
      },
      target: {
        title: '替换零部件',
        type: 'string',
        default: targetOneOf[0]?.const,
        oneOf: targetOneOf,
      },
    },
  };

  return (
    <PickableCommandForm
      disabled={false}
      isFormDataValid={isFormDataValid()}
      onClose={onClose}
      title={title}
      schema={schema}
      formData={formData}
      onChange={(v) => {
        setFormData(v);
      }}
      extraUiSchema={{
        select: {
          'ui:placeholder': '请输入零件',
          'ui:autofocus': true,
          'ui:options': {
            pickFilter: noSystemReferences,
            allowPickInvisibleAssembleFromLeftPanel: true,
          },
        },
      }}
      submitText='完成'
      onSubmit={checkAndFinish}
    />
  );
}

export const cmdExchangeDoc = {
  id: 'CmdExchangeDoc',
  label: 'command.exchange-part-or-product',
  icon: 'constraints/replace-part',
  create: (label?: string, onClose?: () => void) => (
    <ExchangeDoc
      title={i18n.t(label)}
      onClose={onClose}
    />
  ),
};
